//------------------------------------------------------------------------------
// Fichiers d'ent�te utilis�s
//------------------------------------------------------------------------------
#include "Camera.hpp"
#include "../Tools/vec.hpp"
#include "../Tools/mat44.hpp"
#include "GL/glu.h"

//------------------------------------------------------------------------------
// D�finition de constantes
//------------------------------------------------------------------------------
#define DEFAULT_CAMERA_POSITION_Z 15
#define DEFAULT_FIELD_OF_VIEW 45.0f
namespace Viewer
{
	//----------------------------------------------------------------------
	// Constructeur
	//----------------------------------------------------------------------
	Camera::Camera( )
	{
		// Initialisation de la position de la cam�ra
		Position[0] = 0;
		Position[1] = 0;
		Position[2] = DEFAULT_CAMERA_POSITION_Z;
		Position[3] = 1;

		// Initialisation de la direction de la cam�ra
		Direction[0] = 0;
		Direction[1] = 0;
		Direction[2] = -1;
		Direction[3] = 0;

		// Initialisation du vecteur vertical de la cam�ra
		Up[0] = 0;
		Up[1] = 1;
		Up[2] = 0;
		Up[3] = 0;

		//
		FieldOfView = DEFAULT_FIELD_OF_VIEW;
	}

	Camera::~Camera()
	{
	}

	//----------------------------------------------------------------------
	// Constructeur
	//----------------------------------------------------------------------
	void Camera::Print( )
	{
		printf("Camera::Position[%f,%f,%f,%f]\n",Position[0],Position[1],Position[2],Position[3]);
		printf("Camera::Direction[%f,%f,%f,%f]\n",Direction[0],Direction[1],Direction[2],Direction[3]);
		printf("Camera::Up[%f,%f,%f,%f]\n",Up[0],Up[1],Up[2],Up[3]);
	}

	//----------------------------------------------------------------------
	// D�place la cam�ra verticalement
	//----------------------------------------------------------------------
	void Camera::MoveVertical( float distance )
	{
		Tools::vec4_add_const_mul( Position, Position, distance, Up);
	}

	//----------------------------------------------------------------------
	// D�place la cam�ra horizontalement
	//----------------------------------------------------------------------
	void Camera::MoveHorizontaly( float distance )
	{
		float right[4];
		Tools::vec4_init(right,0,0,0,0);
		Tools::vec3_cross( right, Direction, Up );
		Tools::vec4_add_const_mul( Position, Position, distance, right);
	}

	//----------------------------------------------------------------------
	// D�place la cam�ra en profondeur
	//----------------------------------------------------------------------
	void Camera::MoveDeeply( float distance )
	{
		Tools::vec4_add_const_mul( Position, Position, distance, Direction);
	}

	//----------------------------------------------------------------------
	// Tourne la cam�ra sur elle m�me selon l'axe et l'angle donn�s
	//----------------------------------------------------------------------
	void Camera::RotateCameraAxis( float* axis, float angle )
	{
		float rotationMatrix[16];
		float transformedDirection[4];
		float transformedUp[4];

		Tools::mat44_rotate(rotationMatrix, angle, axis[0], axis[1], axis[2] );

		Tools::mat44_mul_vec(transformedDirection, rotationMatrix, Direction );
		Tools::mat44_mul_vec(transformedUp, rotationMatrix, Up );

		Tools::vec4_norm(transformedDirection,transformedDirection);
		Tools::vec4_norm(transformedUp,transformedUp);

		Tools::vec4_copy(Direction, transformedDirection );
		Tools::vec4_copy(Up, transformedUp );
	}

	void Camera::RotateCamera( float angleX, float angleY )
	{
		float right[4];
		Tools::vec4_init(right,0,0,0,0);
		Tools::vec3_cross( right, Direction, Up );

		float axisZ[4];
		Tools::vec4_init(axisZ,0,0,1,0);
		//RotateCameraAxis( camera, right, angleX );
		RotateCameraAxis( Up, angleX );
		//RotateCameraAxis( camera, axisZ, angleY);
		RotateCameraAxis( Up, angleY);
	}
}